using System;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization.Formatters.Binary;

namespace SBPweb.Components
{
	/// <summary>
	/// Class of ComponentPersister
	/// </summary>
	/// <typeparam name="TType"></typeparam>
	public sealed class ComponentPersister<TType>
	{
        private static BinaryFormatter mFormatter;

        private ComponentPersister()
        {
        }

		/// <summary>
		/// Constructor of ComponentPersister
		/// </summary>
		static ComponentPersister()
		{
			mFormatter = new BinaryFormatter();
			mFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full;
			mFormatter.FilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
			mFormatter.TypeFormat = System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesAlways;
		}

		/// <summary>
		/// Serialize to stream
		/// </summary>
		/// <param name="component">component</param>
		/// <returns>stream</returns>
		public static Stream SerializeToStream(TType component)
		{
			Stream stream = new MemoryStream();

			mFormatter.Serialize(stream, component);

			stream.Flush();
			stream.Position = 0;

			return stream;
		}

		/// <summary>
		/// Serialize to byte array
		/// </summary>
		/// <param name="component">comopnent</param>
		/// <returns>byte array</returns>
		public static byte[] SerializeToByteArray(TType component)
		{
            MemoryStream stream = (MemoryStream)SerializeToStream(component);

            int length = (int)stream.Length;

            byte[] bytes = (byte[])Array.CreateInstance(typeof(byte), length);

            if (stream.CanRead)
            {
                stream.Read(bytes, 0, length);
            }

            return bytes;
		}

		/// <summary>
		/// Serialize to string
		/// </summary>
		/// <param name="component">component</param>
		/// <returns>string</returns>
        public static string SerializeToString(TType component)
        {
            StreamReader reader = new StreamReader(SerializeToStream(component), System.Text.Encoding.Default, true);
            return reader.ReadToEnd();
        }

		/// <summary>
		/// Deserialize from stream
		/// </summary>
		/// <param name="stream">stream</param>
		/// <returns>type</returns>
        public static TType DeserializeFromStream(Stream stream)
		{
			stream.Flush();
			stream.Position = 0;

			object obj = mFormatter.Deserialize(stream);

			return (TType)obj;
		}

		/// <summary>
		/// Deserialize from byte array
		/// </summary>
		/// <param name="byteArray">byte array</param>
		/// <returns>type</returns>
		public static TType DeserializeFromByteArray(byte[] byteArray)
		{
            MemoryStream stream = new MemoryStream(byteArray);

            return DeserializeFromStream(stream);
		}

		/// <summary>
		/// Deserialize from string
		/// </summary>
		/// <param name="value">string</param>
		/// <returns>type</returns>
        public static TType DeserializeFromString(string value)
        {
            byte[] bytes = System.Text.Encoding.Default.GetBytes(value);

            return DeserializeFromByteArray(bytes);
        }

		private static object ExtractHeaders(Header[] headers)
		{
			return headers;
		}


	}
}
